﻿using JewererBasic;
using JewererBasic.Models;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Data.Entity;
using JewererBasic.Classes;
using JewererBasic.BO;

namespace JewererBasic.Controllers
{
    public class NewProductController : Controller
    {
        private static string drawing = "";

        #region create       
        public ActionResult Index()
        {
            PRODUCT pro = new PRODUCT();
            this.SetViewBag(pro);
            return View(pro);
        }

        // Get Data Here
        [HttpPost]
        public ActionResult AllPostHere(
            List<CastingView> castings,
            List<StoneView> stones,
            List<ComponentView> components,
            List<ProcessView> processes,
            ProductView productView)
        {
            productView.Drawing = NewProductController.drawing;

            // convert from view model to domain model)
            string castingValidate = checkCastingDuplicate(castings);
            string stoneValidate = checkStoneDuplicate(stones);
            string componentValidate = checkComponentDuplicate(components);
            string processValidate =   checkProcessDuplicate(processes);
            if (string.IsNullOrEmpty(stoneValidate) == false ||
                string.IsNullOrEmpty(componentValidate) == false ||
                string.IsNullOrEmpty(processValidate) == false ||
                string.IsNullOrEmpty(castingValidate) == false)
            {
                string err = castingValidate + stoneValidate + processValidate + componentValidate;
                return Json(new { Success = "False", Err = err, RedirectTo = "" });
                //return new JsonResult { Data = new { Success = true, responseText=err } };
            }
            PRODUCT product = ViewModelConverter.Convert(productView);
            product.PRODUCT_STONE = ViewModelConverter.Convert(stones);
            product.PRODUCT_PROCESS = ViewModelConverter.Convert(processes);
            product.PRODUCT_COMPONENT = ViewModelConverter.Convert(components);
            product.PRODUCT_MOULD = ViewModelConverter.Convert(castings);

            // save to database
            bool result = ProductBO.SaveProduct(product);
            //if (result == false)
            //    RedirectToAction("Index", "Error");
            //return Json(new { Success = "True", responseText = "Success" });

            UrlHelper h = new UrlHelper(ControllerContext.HttpContext.Request.RequestContext);
            string str = h.Action("Index", "Product", null);
            return Json(new { Success = "True", Err = "", RedirectTo = str});
        }

        //AllPostUpdate
        string checkStoneDuplicate(List<StoneView> list)
        {
            if (list == null)
                return "";
            MSQDBEntities db = new MSQDBEntities();
            string result = "";
            int count = list.Count;
            for (int i = 0; i < count; i++)
            {
                if (db.STONEs.Find(list[i].Item) == null)
                    result += "[Can't find stone: " + list[i].Item + "] ";
            }
            for (int i = 0; i < count - 1; ++i)
                for (int j = i + 1; j < count; j++)
                {
                    if (list[i].Item.Equals(list[j].Item))
                        result += "[Duplicate stone: " + list[i].Item + "] ";
                }
            return result;
        }

        string checkComponentDuplicate(List<ComponentView> list)
        {
            if (list == null)
                return "";
            MSQDBEntities db = new MSQDBEntities();
            string result = "";
            int count = list.Count;
            for (int i = 0; i < count; i++)
            {
                if (db.COMPONENTs.Find(list[i].Item) == null)
                    result += "[Can't find component: " + list[i].Item + "] ";
            }
            for (int i = 0; i < count - 1; ++i)
                for (int j = i + 1; j < count; j++)
                {
                    if (list[i].Item.Equals(list[j].Item))
                        result += "[Duplicate component: " + list[i].Item + "] ";
                }
            return result;
        }

        string checkProcessDuplicate(List<ProcessView> list)
        {
            if (list == null)
                return "";
            MSQDBEntities db = new MSQDBEntities();
            string result = "";
            int count = list.Count;
            for (int i = 0; i < count; i++)
            {
                string name = list[i].NameProcess;
                var query = (from d in db.PROCESSes
                             where string.Equals(d.Name, name)
                             select d).ToList();

                if (query.Count == 0)
                {
                    result += "[Can't find process: " + list[i].NameProcess + "] ";
                }
            }

            for (int i = 0; i < count - 1; ++i)
                for (int j = i + 1; j < count; j++)
                {
                    if (list[i].NameProcess.Equals(list[j].NameProcess))
                        result += "[Duplicate component: " + list[i].NameProcess + "] ";
                }
            return result;
        }

        string checkCastingDuplicate(List<CastingView> list)
        {
            if (list == null)
                return "";
            MSQDBEntities db = new MSQDBEntities();
            string result = "";
            int count = list.Count;
            for (int i = 0; i < count; i++)
            {
                if (db.MOULDs.Find(list[i].IdMould) == null)
                    result += "[Can't find mould: " + list[i].IdMould + "] ";
            }
            for (int i = 0; i < count - 1; i++)
                for (int j = i + 1; j < count; j++)
                {
                    if (list[i].IdMould.Equals(list[j].IdMould))
                        result += "[Duplicate casting: " + list[i].IdMould + "] ";
                }
            return result;
        }

        public ActionResult checkDuplicateProductionCart(string nameItem)
        {
            if (string.IsNullOrEmpty(nameItem) == false)
            {
                if (ProductBO.IsExisted(nameItem))
                    return Json("Production Card existed in Database", JsonRequestBehavior.AllowGet);
            }
            return Json("Success", JsonRequestBehavior.AllowGet);
        }

        public void SetViewBag(PRODUCT product)
        {
            MSQDBEntities db = new MSQDBEntities();
            // for product
            ViewBag.IdKind = new SelectList(db.KINDs, "Id", "Name", product.IdKind);
            ViewBag.IdType = new SelectList(db.TYPEs, "Id", "Name", product.IdType);
            ViewBag.IdUnit = new SelectList(db.UNITs, "Id", "Name", product.IdUnit);
            ViewBag.IdGamma = new SelectList(db.GAMMAs, "Id", "Name", product.IdGamma);
        }

        #region autocomplete helpers
        public ActionResult Components(string query = null)
        {
            MSQDBEntities db = new MSQDBEntities();
            var result = from d in db.COMPONENTs
                         where d.Id.Contains(query)
                         select d.Id;
            return Json(result.ToList(), JsonRequestBehavior.AllowGet);
        }

        public ActionResult Moulds(string query = null)
        {
            MSQDBEntities db = new MSQDBEntities();
            var result = from d in db.MOULDs
                         where d.IdMould.Contains(query)
                         select d.IdMould;
            var s = result.ToList();
            return Json(result.ToList(), JsonRequestBehavior.AllowGet);
        }

        public ActionResult Stones(string query = null)
        {
            MSQDBEntities db = new MSQDBEntities();
            var result = from d in db.STONEs
                         where d.Id.Contains(query)
                         select d.Id;
            return Json(result.ToList(), JsonRequestBehavior.AllowGet);
        }

        public ActionResult Units(string query = null)
        {
            MSQDBEntities db = new MSQDBEntities();
            var result = from d in db.UNITs
                         where d.Name.Contains(query)
                         select d.Name;
            return Json(result.ToList(), JsonRequestBehavior.AllowGet);
        }

        public ActionResult Types(string query = null)
        {
            MSQDBEntities db = new MSQDBEntities();
            var result = from d in db.TYPEs
                         where d.Name.Contains(query)
                         select d.Name;
            return Json(result.ToList(), JsonRequestBehavior.AllowGet);
        }

        public ActionResult Processes(string query = null)
        {
            MSQDBEntities db = new MSQDBEntities();
            var result = from d in db.PROCESSes
                         where d.Type==1 && d.Name.Contains(query)
                         select d.Name;
            return Json(result.ToList(), JsonRequestBehavior.AllowGet);
        }
        #endregion
        #endregion

        #region update
        public ActionResult Update(string id)
        {
            var product = ProductBO.Find(id);
            if (product == null)
            {
                ErrorLog.Instance.InternalErrors.Add("Can't find Production Card Id: " + id + " in Database!");
                RedirectToAction("Index", "Error");
            }
            if(string.IsNullOrEmpty(product.Drawing)==false)
                NewProductController.drawing = product.Drawing;
            itemProduct = product.Id;
            this.SetViewBag(product);
            return View(product);
        }

        static string itemProduct = null;

        public ActionResult GetDataForUpdate()
        {
            PRODUCT pro = ProductBO.Find(NewProductController.itemProduct);
            var castings = ViewModelConverter.Convert(pro.PRODUCT_MOULD.ToList());
            var stones = ViewModelConverter.Convert(pro.PRODUCT_STONE.ToList());
            var components = ViewModelConverter.Convert(pro.PRODUCT_COMPONENT.ToList());
            var processes = ViewModelConverter.Convert(pro.PRODUCT_PROCESS.ToList());
            return Json(new { Success = "True", ca=castings, st=stones, co=components, pr=processes });
        }

        [HttpPost]
        public ActionResult AllPostUpdate(
            List<CastingView> castings,
            List<StoneView> stones,
            List<ComponentView> components,
            List<ProcessView> processes,
            ProductView productView)
        {
            if (processes == null || productView == null)
            {
                string err= "At least 1 stone or component or process exist";
                return Json(new { Success = "False", responseText = err });
            }
            productView.Drawing = NewProductController.drawing;
            // convert from view model to domain model)
            string castingValidate = checkCastingDuplicate(castings);
            string stoneValidate = checkStoneDuplicate(stones);
            string componentValidate = checkComponentDuplicate(components);
            string processValidate = checkProcessDuplicate(processes);
            if (string.IsNullOrEmpty(stoneValidate) == false ||
                string.IsNullOrEmpty(componentValidate) == false ||
                string.IsNullOrEmpty(processValidate) == false ||
                string.IsNullOrEmpty(castingValidate) == false)
            {
                string err = castingValidate + stoneValidate + processValidate + componentValidate;
                //return new JsonResult { Data = new { Success = false, responseText = err } };
                return Json(new { Success = "False", responseText = err });
            }
            PRODUCT product = ViewModelConverter.Convert(productView);
            product.PRODUCT_STONE = ViewModelConverter.Convert(stones);
            product.PRODUCT_PROCESS = ViewModelConverter.Convert(processes);
            product.PRODUCT_COMPONENT = ViewModelConverter.Convert(components);
            product.PRODUCT_MOULD = ViewModelConverter.Convert(castings);
            // save to database
            ProductBO.Update(product);
            //return new JsonResult { Data = new { Success = true } };
            UrlHelper h = new UrlHelper(ControllerContext.HttpContext.Request.RequestContext);
            string str = h.Action("Index", "Product", null);
            return Json(new { Success = "True", Err = "", RedirectTo = str });
        }
      
        [HttpPost]
        public ActionResult Update(ProductView pro)
        {
            return RedirectToAction("Index", "Product");
        }
        #endregion

        #region Upload file
        [HttpPost]
        public virtual ActionResult UploadFile()
        {
            HttpPostedFileBase myFile = Request.Files["MyFile"];
            bool isUploaded = false;
            string message = "File upload failed";

            if (myFile != null && myFile.ContentLength != 0)
            {
                string pathForSaving = Server.MapPath("~/Uploads");
                if (this.CreateFolderIfNeeded(pathForSaving))
                {
                    try
                    {
                        myFile.SaveAs(Path.Combine(pathForSaving, myFile.FileName));
                        isUploaded = true;
                        message = "File uploaded successfully!";
                        NewProductController.drawing = myFile.FileName;
                    }
                    catch (Exception ex)
                    {
                        message = string.Format("File upload failed: {0}", ex.Message);
                    }
                }
            }
            return Json(new { isUploaded = isUploaded, message = message, filename = myFile.FileName}, "text/html");
        }
        private bool CreateFolderIfNeeded(string path)
        {
            bool result = true;
            if (!Directory.Exists(path))
            {
                try
                {
                    Directory.CreateDirectory(path);
                }
                catch (Exception)
                {
                    result = false;
                }
            }
            return result;
        }
        #endregion

        #region Detail
        public ActionResult Details(string productId)
        {
            MSQDBEntities dc=new MSQDBEntities();
            return View(dc.PRODUCTs.Find(productId));
        }
        #endregion
    }
}
